package handler

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/zeromicro/go-zero/rest/httpx"
	"gopkg.in/mgo.v2/bson"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
	"zero-demo-rpc/chainmaker"
	"zero-demo-rpc/mall/MakeProduct/api/internal/logic"
	"zero-demo-rpc/mall/MakeProduct/api/internal/svc"
	"zero-demo-rpc/mall/MakeProduct/api/internal/types"
)

const (
	defaultMultipartMemory = 32 << 20 // 32 MB
)
const UPLOAD_PATH string = "/home/zero-demo-rpc/UserImages/"

type Img struct {
	Id     bson.ObjectId `bson:"_id"`
	ImgUrl string        `bson:"imgUrl"`
}

type Info struct {
	UserName    string `db:"UserName"`
	NftName     string `db:"NftName"`
	Description string `db:"Description"`
	Amount      int    `db:"Amount"`
}

func makeProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {

		w.Header().Set("Access-Control-Allow-Origin", "*")

		var req types.MakeReq
		l := logic.NewMakeProductLogic(r.Context(), svcCtx)
		resp, err := l.MakeProduct(&req)

		UserName := r.FormValue("UserName")
		NftName := r.FormValue("NftName")
		Description := r.FormValue("Description")
		Amount := r.FormValue("Amount")

		db, err := sql.Open("mysql", "root:huohuo@tcp(127.0.0.1:3306)/test_2?charset=utf8")

		if err != nil {
			fmt.Println("数据库连接失败:", err)
			return
		}

		//Get index
		rows, err := db.Query("SELECT total FROM indexs where num=1")
		s := 0
		if err != nil {
			fmt.Println("获取索引失败:", err)
			return
		} else {
			for rows.Next() {
				err := rows.Scan(&s)
				fmt.Println(err)
			}
			fmt.Println("总铸造次数:", s)
		}

		s += 1

		//更新一下总数，确保唯一
		_, err = db.Exec("UPDATE indexs SET total=? where num=1", s)

		timeStr1 := time.Now().Format("2006-01-02 15:04:05")
		result, err := db.Exec("INSERT INTO product_list(user_name,product_name,product_id,product_description,product_count,post_time,product_state,product_url) VALUES (?,?,?,?,?,?,?,?)", UserName, NftName, s, Description, Amount, timeStr1, 1, "uploading.png")

		if err != nil {
			fmt.Println("添加至数据库失败:", err)
			return
		} else {
			fmt.Println("Insert Product SUCCESS:", result, "，开始上链")
		}

		print("尝试保存图片")
		var img Img
		img.Id = bson.NewObjectId()
		r.ParseMultipartForm(1024 * 1024)
		imgFile, imgHead, imgErr := r.FormFile("Img")
		if imgErr != nil {
			fmt.Println(imgErr)
			return
		}
		defer imgFile.Close()
		imgFormat := strings.Split(imgHead.Filename, ".")
		img.ImgUrl = img.Id.Hex() + "." + imgFormat[len(imgFormat)-1]

		image, err := os.Create(UPLOAD_PATH + img.ImgUrl)
		if err != nil {
			fmt.Println(err)
			return
		}
		defer image.Close()

		fmt.Println("正在复制文件至服务器：")

		_, err = io.Copy(image, imgFile)
		if err != nil {
			fmt.Println(err)
			return
		}

		fmt.Println("添加文件成功，添加索引至数据库中：")

		fmt.Println("图片id:", img.Id, "图片索引：", img.ImgUrl)

		tradeid, contractid, err := AddToChain(int64(s), img.ImgUrl)
		fmt.Println("tradeid:", tradeid, "contractid:", contractid)

		//瞎编一个合约标识，其实没有这个东西
		contractinfo := 12121
		//获取当前时间，这个是固定写法，里面的时间是golang诞生的时间
		timeStr2 := time.Now().Format("2006-01-02 15:04:05")

		if err != nil {
			fmt.Println("铸造失败,标记状态为0", err)
			_, err := db.Exec("UPDATE product_list SET product_url=?,product_state=2,contract_address=?,contract_info=? where product_id=?", img.ImgUrl, contractid, contractinfo, s)
			if err != nil {
				fmt.Println(err)
			}
			//铸造失败了，理论上没有详情信息的
			_, err = db.Exec("INSERT INTO product_info(product_id,product_url,trade_id,trade_time) VALUES (?,?,?,?)", s, img.ImgUrl, "", "")

		} else {
			_, err := db.Exec("UPDATE product_list SET product_url=?,product_state=2,contract_address=?,contract_info=? where product_id=?", img.ImgUrl, contractid, contractinfo, s)
			if err != nil {
				fmt.Println(err)
			}
			_, err = db.Exec("INSERT INTO product_info(product_id,product_url,trade_id,trade_time) VALUES (?,?,?,?)", s, img.ImgUrl, tradeid, timeStr2)
		}

		resp = &types.MakeReply{
			Result: "This is a Respose",
		}

		httpx.OkJson(w, resp)

		fmt.Println("Return INfo")

		/*
			var req types.MakeReq
			if err := httpx.Parse(r, &req); err != nil {
				httpx.Error(w, err)

				print("获取请求错误")

				return
			}

			l := logic.NewMakeProductLogic(r.Context(), svcCtx)

			resp, err := l.MakeProduct(&req)

			if err != nil {
				httpx.Error(w, err)
			} else {
				httpx.OkJson(w, resp)
			}
		*/

	}
}

func AddToChain(tokenId int64, url string) (result string, contractAddress string, err error) {

	sdkConfPath := "/home/zero-demo-rpc/chainmaker/example/config_mylocal/sdk_config_org1_admin1.yml"
	nftABIPath := "/home/zero-demo-rpc/chainmaker/example/config_mylocal/nft_normal.abi"
	cryptoGenConfPath := "/home/zero-demo-rpc/chainmaker/example/config_mylocal/crypto_config.yml"
	//basePath = "/home/zero-demo-rpc/chainmaker/example/config_mylocal/wx-org1.chainmaker.org"
	contractName := "nft_normal"
	//admin1addr = "0x435efa08c7d7cfb9cc06ba572f2cad9e53060fb6"
	admin1addr := "0x55f00c94f8579a75be0fc896c87b79cca963f2ab"

	cm, err := chainmaker.NewChainMaker(sdkConfPath, nftABIPath, cryptoGenConfPath)
	if err != nil {
		fmt.Println("生成上链连接失败：", err)
		return "", "", err
	}

	contract_Address, err := cm.QueryContract(contractName, "owner", -1)
	fmt.Println(contract_Address)

	if err != nil {
		fmt.Println("合约查询失败：", err)
	} else {
		//contractAddress := contract_Address
		contractAddress = "0x435EFa08c7D7cfb9CC06Ba572F2Cad9e53060FB6"
		fmt.Println("合约地址：", contractAddress)
	}

	_, result, err = cm.Mint(contractName, admin1addr, tokenId, url)

	if err != nil {
		fmt.Println("铸造失败：", err)
		return "", "", nil
	} else {
		fmt.Println("铸造成功，交易哈希值：", result)
		return result, contractAddress, nil
	}

}
